﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using RooHui.Portal.Biz.Model;
using RooHui.Infrastructure.Entities.EFContext;
using RooHui.Infrastructure.Entities.Enum;
using RooHui.Infrastructure.Entities.Entity;
using RooHui.Infrastructure.Entities;

namespace RooHui.Portal.Biz
{
    public class InvestmentBiz
    {
        public static InvestmentInfoModel GetMemberInvestmentInfo(string userName)
        {
            InvestmentInfoModel info = new InvestmentInfoModel();
            using (Context ctx = new Context())
            {
                var list = (from c in ctx.Order
                            where c.UserName == userName
                            join p in ctx.Project
                             on c.ProjectId equals p.ID
                            select new { p.Status, c.Amount})
                           .ToList();

                var invest = list.Where(c => c.Status == (int)ProjectStatus.Publish || c.Status == (int)ProjectStatus.Full)
                    .ToList();
                info.Invest = new InvestmentItemModel();
                if (invest != null)
                {
                    info.Invest.Count = invest.Count();
                    info.Invest.Amount = invest.Sum(c => c.Amount);
                }

                var repayment = list.Where(c => c.Status == (int)ProjectStatus.Repayment).ToList();
                info.Repayment = new InvestmentItemModel();
                if (repayment != null)
                {
                    info.Repayment.Count = repayment.Count();
                    info.Repayment.Amount = repayment.Sum(c => c.Amount);
                }

                var complete = list.Where(c => c.Status == (int)ProjectStatus.Complete).ToList();
                info.Complete = new InvestmentItemModel();
                if (complete != null)
                {
                    info.Complete.Count = complete.Count();
                    info.Complete.Amount = complete.Sum(c => c.Amount);
                }

                info.Total = new InvestmentItemModel();
                info.Total.Count = info.Complete.Count + info.Invest.Count + info.Repayment.Count;
                info.Total.Amount = info.Complete.Amount + info.Invest.Amount + info.Repayment.Amount;

                return info;
            }
        }

        public static PayBackInfomodel GetMemberRepaymentInfo(string userName)
        {
            using (Context ctx = new Context())
            {
                var data = (from c in ctx.PayBackItem
                            where c.UserName == userName
                            select c).ToList();
                DateTime thisMonthFirstDay = new DateTime(DateTime.Now.Year, DateTime.Now.Month, 1);
                DateTime thisYearFirstDay = new DateTime(DateTime.Now.Year, 1, 1);
                return new PayBackInfomodel()
                {
                    ThisMonth = new InvestmentItemModel()
                    {
                        startDate = thisMonthFirstDay,
                        endDate = thisMonthFirstDay.AddMonths(1).AddDays(-1).Add(new TimeSpan(23, 59, 59)),
                        Count = data.Count(c => c.PayBackDate >= thisMonthFirstDay &&
                            c.PayBackDate <= thisMonthFirstDay.AddMonths(1).AddDays(-1).Add(new TimeSpan(23, 59, 59))),
                        Amount = data.Where(c => c.PayBackDate >= thisMonthFirstDay &&
                            c.PayBackDate <= thisMonthFirstDay.AddMonths(1).AddDays(-1).Add(new TimeSpan(23, 59, 59))).Sum(c => c.PayBackInterest + c.PayBackPrincipal)
                    },
                    NextMonth = new InvestmentItemModel()
                    {
                        startDate = thisMonthFirstDay.AddMonths(1),
                        endDate= thisMonthFirstDay.AddMonths(2).AddDays(-1).Add(new TimeSpan(23, 59, 59)),
                        Count = data.Count(c => c.PayBackDate >= thisMonthFirstDay.AddMonths(1) &&
                            c.PayBackDate <= thisMonthFirstDay.AddMonths(2).AddDays(-1).Add(new TimeSpan(23, 59, 59))),
                        Amount = data.Where(c => c.PayBackDate >= thisMonthFirstDay.AddMonths(1) &&
                            c.PayBackDate <= thisMonthFirstDay.AddMonths(2).AddDays(-1).Add(new TimeSpan(23, 59, 59))).Sum(c => c.PayBackInterest + c.PayBackPrincipal)
                    },
                    AllYearMonth = new InvestmentItemModel()
                    {
                        startDate = thisYearFirstDay,
                        endDate = thisYearFirstDay.AddYears(1).AddDays(-1).Add(new TimeSpan(23, 59, 59)),
                        Count = data.Count(c => c.PayBackDate >= thisYearFirstDay &&
                               c.PayBackDate <= thisYearFirstDay.AddYears(1).AddDays(-1).Add(new TimeSpan(23, 59, 59))),
                        Amount = data.Where(c => c.PayBackDate >= thisYearFirstDay &&
                            c.PayBackDate <= thisYearFirstDay.AddYears(1).AddDays(-1).Add(new TimeSpan(23, 59, 59))).Sum(c => c.PayBackInterest + c.PayBackPrincipal)
                    },
                    TotalMonth = new InvestmentItemModel()
                    {
                        Count = data.Count,
                        Amount = data.Sum(c => c.PayBackInterest + c.PayBackPrincipal)
                    }
                };
            }
        }

        /// <summary>
        /// 
        /// </summary>
        /// <param name="userName"></param>
        /// <param name="type">0：全部 1：投标中 2：汇款中 3：完成</param>
        /// <param name="start"></param>
        /// <param name="end"></param>
        /// <returns></returns>
        public static ItemListBox<InvestmentItemsModel> GetMemberInvestmentList(string userName, 
            int type, string start, string end, int page, int pageSize)
        {
            using (Context ctx = new Context())
            {
                var query = from c in ctx.Order
                           where c.UserName == userName
                           join p in ctx.Project
                            on c.ProjectId equals p.ID
                           join g in ctx.GuaranteeCompany
                            on p.GuaranteeCompanyID equals g.ID
                           join op in ctx.OrderPolicy
                            on c.ID equals op.OrderId
                           join o in ctx.Policy
                            on op.PolicyId equals o.ID
                           where !o.IsAttach
                           select new {
                               OrderId = c.ID,
                               c.Amount,
                               c.CreateTime,
                               p.BeginDate,
                               p.Status,
                               p.ProductName,
                               p.ProjectCode,
                               p.ProjectTitle,
                               p.CycleAmount,
                               InvestId = c.ID,
                               PorjectId = p.ID,
                               g.CompanyName,
                               g.LogoImage,
                               o.Rate,
                               o.SettlementType,
                               o.BalanceType
                           };
                if (type > 0)
                {
                    var typeKeys = new List<int>();
                    switch (type)
                    { 
                        default:
                        case 1:
                            typeKeys.Add(4);
                            typeKeys.Add(6);
                            break;
                        case 2:
                            typeKeys.Add(7);
                            break;
                        case 3:
                            typeKeys.Add(8);
                            break;

                    }
                    query = query.Where(c => typeKeys.Contains(c.Status));
                }
                if (!String.IsNullOrEmpty(start))
                {
                    DateTime dtStart = DateTime.Now;
                    if (DateTime.TryParse(start, out dtStart))
                    {
                        query = query.Where(c => c.CreateTime >= dtStart);
                    }
                }
                if (!String.IsNullOrEmpty(end))
                {
                    DateTime dtEnd = DateTime.Now;
                    if (DateTime.TryParse(end, out dtEnd))
                    {
                        dtEnd = dtEnd.Add(new TimeSpan(23, 59, 59));
                        query = query.Where(c => c.CreateTime <= dtEnd);
                    }
                }

                var list = query.OrderByDescending(c=>c.OrderId)
                    .Skip(page * pageSize)
                    .Take(pageSize)
                    .ToList()
                    .Select(c => new InvestmentItemsModel()
                    {
                        OrderId = c.OrderId,
                        Amount = c.Amount,
                        GuaranteeCompanyLogo = c.LogoImage,
                        GuaranteeCompanyName = c.CompanyName,
                        InvestDate = c.CreateTime,
                        BeginDate = c.BeginDate,
                        InvestmentId = c.InvestId,
                        ProductName = c.ProductName,
                        ProjectCode = c.ProjectCode,
                        ProjectId = c.PorjectId,
                        ProjectTile = c.ProjectTitle,
                        ProjectCycleAmount = c.CycleAmount,
                        ProjectStatus = (ProjectStatus)c.Status,
                        Policies = new List<ProjectPolicyModel>(){
                            new ProjectPolicyModel()
                            {
                                Rate = c.Rate,
                                SettlementType = (SettlementType)c.SettlementType,
                                BalanceType = (BalanceType)c.BalanceType
                            }}
                    })
                    .ToList();
                return new ItemListBox<InvestmentItemsModel>(list).BuildPage(
                    query.ToList().GroupBy(c => c.PorjectId).Count(),
                    page, pageSize, new PageParameter() { Style = "Home" });
            }
        }

        public static OrderDetailModel GetOrderDetail(int orderId, string userName)
        {
            using (Context ctx = new Context())
            {
                var data = (from o in ctx.Order
                            join j in ctx.Project
                              on o.ProjectId equals j.ID
                            join e in ctx.Enterprise
                              on j.EnterpriseID equals e.ID
                            join g in ctx.GuaranteeCompany
                              on j.GuaranteeCompanyID equals g.ID
                            join rs in ctx.Resource
                               on j.ID equals rs.RefId
                            join op in ctx.OrderPolicy
                              on o.ID equals op.OrderId
                            join p in ctx.Policy
                              on op.PolicyId equals p.ID
                            join i in ctx.Investment
                              on o.ID equals i.OrderID
                            where o.ID == orderId && o.UserName == userName && rs.Type == (int)ResourceType.ProjectResource && i.Status != (int)InvestmentStatus.Cancel
                            select new
                            {
                                ProjectId = j.ID,
                                ProjectTitle = j.ProjectTitle,
                                ProjectCode = j.ProjectCode,
                                ProductName = j.ProductName,
                                ProjectFinancing = j.Financing,
                                ProjectCycleAmount = j.CycleAmount,
                                ProjectReleaseTime = j.ReleaseTime,
                                ProjectBeginDate = j.BeginDate,
                                ProjectDescription = j.ProjectDescription,
                                ProjectStatus = j.Status,
                                EnterpriseCode = e.EnterpriseCode,
                                EnterpriseCredit = e.EnterpriseCredit,
                                InvestAmount = i.InvestMentAmount,
                                GuaranteeName = g.CompanyName,
                                GuaranteeLogo = g.LogoImage,
                                GuaranteeDescription = g.Description,
                                PolicyAddType = op.AddType,
                                PolicyRate = p.Rate,
                                PolicyId = p.ID,
                                PolicyIsAttach = p.IsAttach,
                                PolicyBalanceType = p.BalanceType,
                                PolicySettlementType = p.SettlementType,
                                PolicyDuration = p.Duration,
                                PolicyDurationType = p.DurationType,
                                PolicyCycleAmount = p.CycleAmount == 0 ? j.CycleAmount : p.CycleAmount,
                                PolicyName = p.PolicyName,
                                InvestId = i.ID,
                                Invester = i.UserName,
                                InvestmentAmount = i.InvestMentAmount,
                                InvestDate = i.CreateTime,
                                ResourceName = rs.Name,
                                ResourcePath = rs.Path,
                                ResourceId = rs.ID,
                                ResourcePrivateLevel = rs.PrivateLevel
                            }).ToList();
                var project = data.GroupBy(c => c.ProjectId).First().First();
                var policies = data.GroupBy(c => c.PolicyId).Select(c => c.FirstOrDefault()).ToList();
                var invests = data.GroupBy(c => c.InvestId).Select(c => c.FirstOrDefault()).ToList();
                var resources = data.GroupBy(c => c.ResourceId).Select(c => c.FirstOrDefault()).ToList();
                return new OrderDetailModel()
                {
                    EnterpriseCode = project.EnterpriseCode,
                    EnterpriseCredit = project.EnterpriseCredit,
                    GuaranteeDescription = project.GuaranteeDescription,
                    GuaranteeLogo = project.GuaranteeLogo,
                    GuaranteeName = project.GuaranteeName,
                    ProductName = project.ProductName,
                    ProjectBeginDate = project.ProjectBeginDate,
                    ProjectCode = project.ProjectCode,
                    ProjectCycleAmount = project.ProjectCycleAmount,
                    ProjectDescription = project.ProjectDescription,
                    ProjectFinancing = project.ProjectFinancing,
                    RemainFinancing = project.ProjectFinancing - invests.Sum(c => c.InvestAmount),
                    ProjectId = project.ProjectId,
                    ProjectTitle = project.ProjectTitle,
                    ProjectReleaseTime = project.ProjectReleaseTime,
                    ProjectStatus = (ProjectStatus)project.ProjectStatus,
                    Policies = policies.Select(c => new ProjectPolicyModel()
                    {
                        AddType = (PolicyAddType)c.PolicyAddType,
                        BalanceType = (BalanceType)c.PolicyBalanceType,
                        CycleAmount = c.PolicyCycleAmount,
                        Duration = c.PolicyDuration,
                        DurationType = (DurationType)c.PolicyDurationType,
                        IsAttach = c.PolicyIsAttach,
                        PolicyName = c.PolicyName,
                        Rate = c.PolicyRate,
                        SettlementType = (SettlementType)c.PolicySettlementType
                    }).ToList(),
                    ProjectInvests = invests.Select(c => new ProjectInvestModel()
                    {
                        Invester = c.Invester,
                        InvestMentAmount = c.InvestAmount,
                        RecordDate = c.InvestDate,
                        Id = c.InvestId
                    }).ToList(),
                    Resources = resources.Select(c => new ProjectResourceModel()
                    {
                        Name = c.ResourceName,
                        Path = c.ResourcePath,
                        PrivateLevel = (PrivateLevel)c.ResourcePrivateLevel
                    }).ToList()
                };
            }
        }

        public static ItemListBox<PayBackItem> GetPayBackItems(string userName,int projectId, string start, string end, int page = 0, int pageSize = 20)
        {
            using (Context ctx = new Context())
            {
                var iquery = from c in ctx.PayBackItem
                             join p in ctx.Project
                                on c.ProjectId equals p.ID
                             where c.UserName == userName
                             select new { c,p.ID, p.ProductName, p.ProjectTitle, p.ProjectCode };
                    //ctx.PayBackItem.Where(c => c.UserName == userName);
                if (projectId > 0)
                {
                    iquery = iquery.Where(c => c.ID == projectId);
                }
                DateTime dtStart = DateTime.Now;
                if (DateTime.TryParse(start, out dtStart))
                {
                    iquery = iquery.Where(c => c.c.PayBackDate >= dtStart);
                }
                DateTime dtEdn = DateTime.Now;
                if (DateTime.TryParse(end, out dtEdn))
                { 
                    dtEdn = dtEdn.Add(new TimeSpan(23,59,59));
                    iquery = iquery.Where(c => c.c.PayBackDate <= dtEdn);
                }
                var count = iquery.Count();
                var list = iquery.OrderBy(c => c.c.PayBackDate)
                    .Skip(page * pageSize)
                    .Take(pageSize)
                    .ToList()
                    .Select(c =>
                    {
                        var pi = new PayBackItem().Set(c.c);
                        pi.ProjectCode = c.ProjectCode;
                        pi.ProductName = c.ProductName;
                        pi.ProjectTitle = c.ProjectTitle;
                        return pi;
                    })
                    .ToList();
                return new ItemListBox<PayBackItem>(list).BuildPage(count, page, pageSize, new PageParameter() { Style = "home" });
            }
        }

        public static Dictionary<int,string> GetInvestProjectNames(string userName)
        {
            using (Context ctx = new Context())
            {
                var data = (from c in ctx.PayBack
                              join p in ctx.Project
                                 on c.ProjectID equals p.ID
                              where c.UserName == userName
                              select new { p.ID, p.ProductName, p.ProjectTitle, p.ProjectCode })
                             .ToList()
                             .ToDictionary(
                             c => c.ID,
                             c => string.Format("{0} {1}，项目编码：{2}", c.ProductName, c.ProjectTitle, c.ProjectCode));
                return data;
            }
        }
    }
}
